#include <iostream>
#include <type_traits>
#include <vector>
#include <string>

std::vector<std::string> vs;

void FuncFooImpl(int, std::true_type) 
{
}

template<typename T>
void FuncFooImpl(T&& t, std::false_type) 
{
    vs.emplace_back(std::forward<T>(t));
}

template<typename T>
void FuncFoo(T&& t)
{
    FuncFooImpl(std::forward<T>(t), 
        std::is_integral< 
            typename std::remove_reference<T>::type>()
        );

    // FuncFooImpl(std::forward<T>(t), 
    //     std::is_integral< 
    //         std::remove_reference_t<T>>()
    //     );
}


class Person {
private:
    std::string name;

public:
    template<typename T, 
        typename = typename std::enable_if<
            !std::is_base_of<Person, typename std::decay<T>::type>()
            >::type
        >
    Person(T&& t) :
        name(std::forward<T>(t))
    {
        static_assert(
            std::is_constructible<std::string, T>(),
            "Paramter t can't be used to construct a std::string"
        );
    }
};

class SpecialPerson : public Person {
public:
    using Person::Person;

    SpecialPerson(const SpecialPerson& r) :
        Person(r)
    {
    }

    SpecialPerson(SpecialPerson&& r) :
        Person(std::move(r))
    {
    }
};

int main() {

    FuncFoo(short(0));

    short s = 1;
    FuncFoo(s);

    {
        Person p("name");

        Person p1(Person("name1"));

        Person p2(p1);

        //Person p3(1);
    }

    {
        SpecialPerson sp("name");

        SpecialPerson sp1(sp);
    }

    return 0;
}